package org.vs.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.vs.util.StringUtil;
import org.web3j.crypto.*;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.admin.Admin;
import org.web3j.protocol.admin.methods.response.PersonalUnlockAccount;
import org.web3j.protocol.core.Request;
import org.web3j.protocol.http.HttpService;
import org.web3j.tx.gas.ContractGasProvider;
import org.web3j.tx.gas.StaticGasProvider;
import org.web3j.protocol.geth.Geth;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.net.URL;

@Slf4j
@Configuration
public class EthConfig {
    @Value("${web3j.client-address}")
    private String rpc;

    @Value("${web3j.credential-address}")
    private String credentialAddress;

    @Value("${web3j.dev-account}")
    private String devAccount;

    @Value("${web3j.dev-password}")
    private String devPassword;

    @Bean
    public Web3j web3j() {
        Web3j web3j = Web3j.build(new HttpService(rpc));
        return web3j;
    }

    @Bean
    public ContractGasProvider contractGasProvider() {
        return new StaticGasProvider(BigInteger.valueOf(1L), BigInteger.valueOf(2L));
    }

    @Bean(name = "credential-address")
    public String getCredentialAddress() {
        return credentialAddress;
    }

    @Bean
    public Admin admin() {
        return Admin.build(new HttpService(rpc));
    }

    @Bean
    public Geth geth() {
        return Geth.build(new HttpService(rpc));
    }

    @Bean
    public StaticGasProvider gasProvider() {
        return new StaticGasProvider(BigInteger.valueOf(200000), BigInteger.valueOf(20000000));
    }

    @Bean
    public Credentials getCredentials() throws CipherException, IOException {
        StringBuffer credentialsJson = new StringBuffer();

        InputStream inputStream =
                new URL(StringUtil.getFilePathInServer(credentialAddress, devAccount)).openStream();

        int temp;
        while ((temp = inputStream.read()) != -1) {
            credentialsJson.append((char) temp);
        }

        Credentials credentials = WalletUtils.loadJsonCredentials(devPassword,
                credentialsJson.toString());

        Request<?, PersonalUnlockAccount> request = admin()
                .personalUnlockAccount(credentials.getAddress(), devPassword, BigInteger.valueOf(0));
        PersonalUnlockAccount account = request.send();

        log.info("dev 账户是否解锁 {}", account.accountUnlocked());

        return credentials;
    }
}
